/*=======================================
 * Authors: Scott Kellerman, Jim Cesari
 * 5/2/07
 * A Star Algorithm
 * ======================================*/

using System;
using System.Collections.Generic;
using System.Text;
using BookBarter;

namespace AStar
{
    class FindTradeRoute
    {
        int depth = 0;
        BookWant initialWant;
        List<BookHave> startHaves = new List<BookHave>();
        TempTradeRoute FINAL_TRADE_ROUTE = new TempTradeRoute();

        //default constructor
        public FindTradeRoute()
        {
        }

        //Precondition: Accepts person object
        //Postcondition: Returns TradeRoute object
        public TempTradeRoute StartSearch()
        {
            Person person1 = Person.GetRandomPerson();


            startHaves = person1.BookHaves;
            initialWant = randomWant(person1);
            List<BookHave> compareHaves = new List<BookHave>();
            compareHaves = initialWant.Book.FindAllHaves();
            List<TempTradeRoute> TradeRouteList = new List<TempTradeRoute>();


            Boolean SingleLink = false;
            SingleLink = CheckForSingleLinkMatches(compareHaves, TradeRouteList);
            if (SingleLink)
            {
                FINAL_TRADE_ROUTE.MakePermanent();
                return FINAL_TRADE_ROUTE;
            }

            foreach (TempTradeRoute tr in TradeRouteList)
            {
                depth++;
                if( depth > 10)
                {
                    return null;
                }

                List<BookWant> wantsList = new List<BookWant>();
                wantsList = tr.LastLink.Have.Person.BookWants;

                foreach( BookWant want in wantsList)
                {
                    List<BookHave> NextHaveList = new List<BookHave>();
                    NextHaveList = want.Book.FindAllHaves();
                    foreach (BookHave bh in NextHaveList)
                    {
                        List<BookWant> NextWantList = new List<BookWant>(bh.Person.BookWants);
                        for( int i = 0; i > startHaves.Count; i++)
                        {
                            if (bh.Book == startHaves[i].Book)
                            {
                                return tr;
                            }
                        }
                        foreach (BookHave sh in startHaves)
                        {
                            Boolean completedTradeRoute = false;
                            completedTradeRoute = AddLinkToRoute(NextWantList, TradeRouteList, sh);
                            if (completedTradeRoute)
                            {
                                FINAL_TRADE_ROUTE.MakePermanent();
                                return FINAL_TRADE_ROUTE;
                            }//end if
                        }
                    }
                }
                
            }
            return null;
        }

        //Precondition: accepts person object
        //Postcondition: returns psudeo random want from person's list of wants
        private BookWant randomWant( Person person1 )
        {
            Random rand = new Random();
            BookWant initialWant = person1.BookWants[rand.Next(0, person1.BookWants.Count)];
            return initialWant;
        }

        private Boolean AddLinkToRoute(List<BookWant> NextWantList, List<TempTradeRoute> TradeRouteList, BookHave sh)
        {
            for (int z = 0; z < NextWantList.Count; z++)
            {
                TempTradeRoute traderoute = new TempTradeRoute();
                traderoute = TradeRouteList[z];
                
                if (NextWantList[z].Book == sh.Book)
                {
                    TempTradeLink t = new TempTradeLink(sh, NextWantList[z]);
                    traderoute.AddTradeChainLink(t);
                    FINAL_TRADE_ROUTE = traderoute;
                    return true;
                }

                else
                {
                    TradeRouteList.Add(traderoute);
                }
            }
            return false;
        }

        private Boolean CheckForSingleLinkMatches( List<BookHave> compareHaves, List<TempTradeRoute> TradeRouteList )
        {
            for (int i = 0; i > compareHaves.Count; i++)
            {
                TempTradeRoute tradeRoute1 = new TempTradeRoute();
                TempTradeLink t = new TempTradeLink(compareHaves[i], initialWant);
                tradeRoute1.AddTradeChainLink(t);
                TradeRouteList.Add(tradeRoute1);

                for (int x = 0; x > startHaves.Count; x++)
                {
                    List<BookWant> wantList = new List<BookWant>(t.Have.Person.BookWants);
                    if (startHaves[x].Book == wantList[i].Book)
                    {
                        FINAL_TRADE_ROUTE = tradeRoute1;
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
